using System;
using Saltarelle;
using Saltarelle.UI;

#if CLIENT
using System.DHTML;
#endif

namespace DemoWeb {
#if CLIENT
	public class DragDropTestControlSimpleDragEventArgs : EventArgs {
		public object Data;

		public DragDropTestControlSimpleDragEventArgs(object data) {
			this.Data = data;
		}
	}

	public class DragDropTestControlQueryDropEventArgs : EventArgs {
		public object SourceData;
		public IDropTarget Target;
		public object TargetData;
		public bool Allow;

		public DragDropTestControlQueryDropEventArgs(object sourceData, IDropTarget target, object targetData) {
			this.SourceData = sourceData;
			this.Target = target;
			this.TargetData = targetData;
			this.Allow = true;
		}
	}

	public class DragDropTestControlDragDropCompletedEventArgs : EventArgs {
		public object SourceData;
		public IDropTarget Target;
		public object TargetData;

		public DragDropTestControlDragDropCompletedEventArgs(object sourceData, IDropTarget target, object targetData) {
			this.SourceData = sourceData;
			this.Target = target;
			this.TargetData = targetData;
		}
	}

	public class DragDropTestControlDragEnterLeaveEventArgs : EventArgs {
		public IDragSource Source;
		public object SourceData;

		public DragDropTestControlDragEnterLeaveEventArgs(IDragSource source, object sourceData) {
			this.Source = source;
			this.SourceData = sourceData;
		}
	}

	public class DragDropTestControlDropEventArgs : EventArgs {
		public IDragSource Source;
		public object SourceData;
		public object TargetData;
		public LeftTop CursorPos;

		public DragDropTestControlDropEventArgs(IDragSource source, object sourceData, object targetData, LeftTop cursorPos) {
			this.Source = source;
			this.SourceData = sourceData;
			this.TargetData = targetData;
			this.CursorPos = cursorPos;
		}
	}

	public class DragDropTestControlDragOverEventArgs : EventArgs {
		public IDragSource Source;
		public object SourceData;
		public object TargetData;
		public LeftTop CursorPos;

		public DragDropTestControlDragOverEventArgs(IDragSource source, object sourceData, LeftTop cursorPos) {
			this.Source = source;
			this.SourceData = sourceData;
			this.TargetData = null;
			this.CursorPos = cursorPos;
		}
	}
	
	public delegate void DragDropTestControlSimpleDragEventHandler(object sender, DragDropTestControlSimpleDragEventArgs e);
	public delegate void DragDropTestControlQueryDropEventHandler(object sender, DragDropTestControlQueryDropEventArgs e);
	public delegate void DragDropTestControlDragDropCompletedEventHandler(object sender, DragDropTestControlDragDropCompletedEventArgs e);
	public delegate void DragDropTestControlDragEnterLeaveEventHandler(object sender, DragDropTestControlDragEnterLeaveEventArgs e);
	public delegate void DragDropTestControlDropEventHandler(object sender, DragDropTestControlDropEventArgs e);
	public delegate void DragDropTestControlDragOverEventHandler(object sender, DragDropTestControlDragOverEventArgs e);
#endif

#if SERVER
	[RequiresClientService(typeof(ISaltarelleUIService))]
#endif
	public partial class DragDropTestControl : IControl
	#if CLIENT
	, IDragSource, IDropTarget
	#endif
	{

#if SERVER
		public int NumItems { get { return numItems; } set { numItems = value; } }

		private void Constructed() {
		}
#endif
	
#if CLIENT
		private void Constructed() {
		}
		
		private void Attached() {
			ISaltarelleUIService svc = (ISaltarelleUIService)GlobalServices.GetService(typeof(ISaltarelleUIService));
			svc.RegisterDropTarget(GetElement(), this);

			DOMElement el = GetElement().Children[0];
			for (int i = 0; i < el.Children.Length; i++) {
				svc.MakeDraggable(this, el.Children[i], i, Window.Document.Body);
			}
		}

		public event DragDropTestControlSimpleDragEventHandler HandleDragStarted;
		public event DragDropTestControlSimpleDragEventHandler HandleDragDropCancelled;
		public event DragDropTestControlQueryDropEventHandler HandleQueryDrop;
		public event DragDropTestControlDragDropCompletedEventHandler HandleDragDropCompleted;
		public event DragDropTestControlDragEnterLeaveEventHandler HandleDragEnter;
		public event DragDropTestControlDragEnterLeaveEventHandler HandleDragLeave;
		public event DragDropTestControlDropEventHandler HandleDrop;
		public event DragDropTestControlDragOverEventHandler HandleDragOver;

		public void DragStarted(object data, DOMElement helper) {
			OnHandleDragStarted(new DragDropTestControlSimpleDragEventArgs(data));
		}
		
		public DOMElement CreateDragHelper(object data) {
			return null;
		}

		public void DragDropCancelled(object data) {
			OnHandleDragDropCancelled(new DragDropTestControlSimpleDragEventArgs(data));
		}

		public bool QueryDrop(IDropTarget target, object sourceData, object targetData) {
			DragDropTestControlQueryDropEventArgs e = new DragDropTestControlQueryDropEventArgs(sourceData, target, targetData);
			OnHandleQueryDrop(e);
			return e.Allow;
		}

		public void DragDropCompleted(IDropTarget target, object sourceData, object targetData) {
			OnHandleDragDropCompleted(new DragDropTestControlDragDropCompletedEventArgs(sourceData, target, targetData));
		}

		public void DragEnter(IDragSource dragSource, object sourceData) {
			OnHandleDragEnter(new DragDropTestControlDragEnterLeaveEventArgs(dragSource, sourceData));
		}

		public void DragLeave(IDragSource dragSource, object sourceData) {
			OnHandleDragLeave(new DragDropTestControlDragEnterLeaveEventArgs(dragSource, sourceData));
		}

		public object DragOver(IDragSource dragSource, object sourceData, LeftTop cursorPos) {
			DragDropTestControlDragOverEventArgs e = new DragDropTestControlDragOverEventArgs(dragSource, sourceData, cursorPos);
			OnHandleDragOver(e);
			return e.TargetData;
		}

		public void Drop(IDragSource dragSource, object sourceData, object targetData, LeftTop cursorPos) {
			OnHandleDrop(new DragDropTestControlDropEventArgs(dragSource, sourceData, targetData, cursorPos));
		}

		private void OnHandleDragDropCancelled(DragDropTestControlSimpleDragEventArgs e) {
			if (!Utils.IsNull(HandleDragDropCancelled))
				HandleDragDropCancelled(this, e);
		}

		private void OnHandleDragStarted(DragDropTestControlSimpleDragEventArgs e) {
			if (!Utils.IsNull(HandleDragStarted))
				HandleDragStarted(this, e);
		}

		private void OnHandleQueryDrop(DragDropTestControlQueryDropEventArgs e) {
			if (!Utils.IsNull(HandleQueryDrop))
				HandleQueryDrop(this, e);
		}

		private void OnHandleDragDropCompleted(DragDropTestControlDragDropCompletedEventArgs e) {
			if (!Utils.IsNull(HandleDragDropCompleted))
				HandleDragDropCompleted(this, e);
		}

		private void OnHandleDragEnter(DragDropTestControlDragEnterLeaveEventArgs e) {
			if (!Utils.IsNull(HandleDragEnter))
				HandleDragEnter(this, e);
		}

		private void OnHandleDragLeave(DragDropTestControlDragEnterLeaveEventArgs e) {
			if (!Utils.IsNull(HandleDragLeave))
				HandleDragLeave(this, e);
		}

		private void OnHandleDrop(DragDropTestControlDropEventArgs e) {
			if (!Utils.IsNull(HandleDrop))
				HandleDrop(this, e);
		}

		private void OnHandleDragOver(DragDropTestControlDragOverEventArgs e) {
			if (!Utils.IsNull(HandleDragOver))
				HandleDragOver(this, e);
		}
#endif
	}
}